/*
  A class to select two individuals from a population to reproduce. 
 The probability of being chosen is inversely proportional to the
 rank of the individual by fitness.
 *   
 */

package simple;

import algorithm.BreedingSelector;
import algorithm.Environment;
import algorithm.Individual;
import algorithm.Population;
import java.security.UnrecoverableEntryException;

/**
 *
 * @author vermaak
 */
public class RankRouletteWheelSelector implements BreedingSelector {

    public Individual select(Population pop, Environment environment) throws Exception {
        // order the population by fitness
        pop.sort(environment);
        int n = pop.getSize();
        // get the sum of ranks of the population
        int sumOfRanks = (n+1)*n/2;
        // create random number between zero and the sum
        double ran = Math.random()*sumOfRanks;
        // step through the population and choose the one 
        int sum = 0;
        for (int i=0;i<n;++i) {
            sum += n-i;
            if (sum > ran) {
                return pop.getIndividual(i);
            }
        }
        // if we get here, the random number 
        // was actually larger than the sum of ranks?
        // should be impossible
        throw new Exception("Impossible code to reach. BAD");
    }

}
